package com.zlyx.easy.swagger.plugins;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;

import com.google.common.base.Optional;
import com.zlyx.easy.core.tool.StringFormat;
import com.zlyx.easy.core.utils.ObjectUtils;
import com.zlyx.easy.core.utils.StringUtils;
import com.zlyx.easy.swagger.annotations.SpringMapping;
import com.zlyx.easy.swagger.config.EasySwaggerConfiguration;

import io.swagger.annotations.ApiOperation;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.OperationBuilderPlugin;
import springfox.documentation.spi.service.contexts.OperationContext;
import springfox.documentation.spring.web.DescriptionResolver;
import springfox.documentation.swagger.common.SwaggerPluginSupport;

@Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER + 1)
public class EasySwaggerOperationNotesReader implements OperationBuilderPlugin {

	private final DescriptionResolver descriptions;

	@Autowired(required = false)
	private EasySwaggerConfiguration apiConfiguration;

	@Autowired
	public EasySwaggerOperationNotesReader(DescriptionResolver descriptions) {
		this.descriptions = descriptions;
	}

	@Override
	public void apply(OperationContext context) {
		Optional<SpringMapping> annotation = context.findAnnotation(SpringMapping.class);
		String notes = context.getName();
		if (annotation.isPresent() && !annotation.get().hidden()) {
			if (StringUtils.isNotEmpty(annotation.get().notes())) {
				notes = annotation.get().notes();
			} else if (ObjectUtils.isNotEmpty(annotation.get().todo())) {
				notes = StringFormat.format(annotation.get().todo());
			}
		} else {
			Optional<ApiOperation> apiOperation = context.findControllerAnnotation(ApiOperation.class);
			if (apiOperation.isPresent() && !apiOperation.get().hidden()) {
				if (StringUtils.isNotEmpty(apiOperation.get().notes())) {
					notes = apiOperation.get().notes();
				} else if (StringUtils.isNotEmpty(apiOperation.get().value())) {
					notes = apiOperation.get().value();
				}
			}
		}
		if (apiConfiguration != null && apiConfiguration.isShowPath()) {
			notes += EasySwaggerConfiguration.getTagsName(context.getName());
		}
		context.operationBuilder().notes(descriptions.resolve(notes));
	}

	@Override
	public boolean supports(DocumentationType delimiter) {
		return SwaggerPluginSupport.pluginDoesApply(delimiter);
	}
}
